package Controladores;

import java.awt.Point;
import java.awt.geom.Area;
import java.util.Random;
import java.util.Vector;

import Balas.Bala;
import Juego.Juego;
import Naves.Enemigas.*;

/**Clase que controla por el momento el movimiento de un tipo de enemigos, se desplazan las naves por pantalla y 
 * pueden ser impactadas por balas de tanque
 * 
 * @author Javier Graff
 * @author Eric Avondet
 * @author Rodrigo Herrera
 *
 */
public class Control_Enemigos implements Runnable {

	protected Vector<Nave_Enemiga> naves;
	private Vector<Nave_Enemiga> eliminables;
	private Vector<Nave_Enemiga> agregables;
	protected Juego juego;
	protected boolean terminarhilo;
	protected boolean pausa_movimiento;
	protected boolean pwp_bala_en_pantalla;
	
	
	/**
	 * Constructor, inicializa parametros 
	 * @param j
	 */
	public Control_Enemigos(Juego j)
	{
		terminarhilo=false;
		juego=j;
		naves = new Vector<Nave_Enemiga>();
		eliminables = new Vector<Nave_Enemiga>();
		agregables = new Vector<Nave_Enemiga>();
		pausa_movimiento=false;
		pwp_bala_en_pantalla=false;
	
		//inicializar();	
	}
	
	/**
	 * indica que el powerUp gun esta en pantalla (por lo tanto se debe esperar a que se destruya dicho pwp)
	 */
	public void esta_pwp_bala()
	{
		pwp_bala_en_pantalla=true;
	}
	
	/**
	 * indica que el powerUp gun dejo de estar en pantalla
	 */
	public void no_esta_pwp_bala()
	{
		pwp_bala_en_pantalla=false;
	}
	

	
	/**
	 * carga una nueva flota que atacara al tanque
	 * @param flota
	 */
	public void nueva_flota(Vector<Nave_Enemiga> flota)
	{
		agregables=flota;
	}
	
	/**
	 * envia un impacto de bomba a todos los enemigos en pantalla
	 */
	public void bomba_a_enemigos()
	{
		for (int i=0; i< naves.size(); i++)
		{
			naves.elementAt(i).recibir_bomba();		
		}
	}
	
	
	
	/**
	 * controla si alguna nave colisiona con el tanque
	 */
	public void contorol_impacto_tanque()
	{
		Area areatanque = new Area(juego.getTanque().getBounds());
		for (int i=0; i<naves.size(); i++)
		{
			Area areanave = new Area(naves.elementAt(i).getBounds());
			if (areatanque.intersects(areanave.getBounds2D()))
				juego.getTanque().morir();
		}
	}
	
	
	/**Controla si una bala impacto a alguna nave y realiza las acciones correspondientes
	 * 
	 * @param b bala
	 * @return true si impacto alguna nave, false caso contrario
	 */
	public void controlbalas(Bala b)
	{
		Area areabala = new Area(b.getBounds());
		for (int i=0; i< naves.size(); i++)
		{
			Area areanave = new Area(naves.elementAt(i).getBounds());
			if (areabala.intersects(areanave.getBounds2D()))
				{
					b.impactar(naves.elementAt(i));
				}
		}
	}
	
	/**
	 * Indica que una bala debe ser borrada
	 * @param nave
	 */
	public void agregar_eliminable(Nave_Enemiga nave)
	{
		eliminables.add(nave);
	}
	
	/**indica que una nave debe ser agregada
	 * 
	 * @param nave nave a agregar
	 */
	public void agregar_agregable(Nave_Enemiga nave)
	{
		agregables.add(nave);
	}
	
	/**
	 * agrega las naves indicadas como agregables
	 */
	public void agregar_agregables()
	{
		for (int i=0; i< agregables.size(); i++)
		{
			naves.add(agregables.elementAt(i));
			juego.getgraficos().getGraficoEntidades().getpanel().add(agregables.elementAt(i));
		}
		agregables.removeAllElements();
			
	}
	
	/**
	 * Remueve las balas que deben ser borradas
	 */
	public void remover_eliminables()
	{
		
		
		try {
			Thread.sleep(20);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		for (int i=0; i< eliminables.size(); i++)
			{
				juego.getgraficos().getGraficoEntidades().getpanel().remove(eliminables.elementAt(i));
				juego.getgraficos().getGraficoEntidades().getpanel().repaint();
				naves.remove(eliminables.elementAt(i));
			}
		eliminables.removeAllElements();
	}
	

	
	/**
	 * Movimiento de las naves, si las naves sobrepasan el suelo se reposicionan
	 */
	public void movimiento()
	{
		contorol_impacto_tanque();
		agregar_agregables();
		remover_eliminables();
		
		for (int i=0; i< naves.size(); i++)
		{
			
			naves.elementAt(i).movimiento();
			
			
			Random rn = new Random(/*System.currentTimeMillis()*/);
			if( rn.nextInt(naves.elementAt(i).get_frec_disp()) == 0 ) 
			{
				naves.elementAt(i).disparar();
			}
			
			if (nave_fueraDeRango(naves.elementAt(i)))
				this.agregar_eliminable(naves.elementAt(i));
			
			//if (naves.elementAt(i).getY() > juego.getgraficos().getGraficoEntidades().getpanel().getHeight())
				//setearposicion(naves.elementAt(i));
			
		}
		
	}
	
	/**
	 * controla si la nave esta fuera de rango
	 * @param n nave a controlar
	 * @return true si esta fuera de rango
	 */
	public boolean nave_fueraDeRango(Nave_Enemiga n)
	{
		Point p = n.getLocation();
		boolean bfr=false;
		
		
		if (  (p.getY()>juego.getgraficos().getGraficoEntidades().getpanel().getHeight() )
				|| ( ((p.getX() + n.getWidth())<0) && (p.getY()>0) ) 
				|| ((p.getX()>juego.getgraficos().getGraficoEntidades().getpanel().getWidth()) && (p.getY()>0) )   
			)
			bfr = true;
		
		return bfr;
	}
	
	
	/**
	 * Finaliza el hilo
	 */
	public void terminar_hilo()
	{
		terminarhilo=true;
	}
	
	/**
	 * movimiento de naves en pausa
	 */
	public void pausa()
	{
		pausa_movimiento=true;
	}
	
	/**
	 * continua el movmimiento de naves
	 */
	public void fin_pausa()
	{
		pausa_movimiento=false;
	}
	
	
	
	@Override
	public void run() 
	{
		
		while (!terminarhilo)
		{
			if (naves.isEmpty() && !pwp_bala_en_pantalla) 
				{
					juego.get_inteligencia().enviar_flota();
				}
			
			if (!pausa_movimiento) 
					movimiento();
	
			try {
				Thread.sleep(40);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
		
		// TODO Auto-generated method stub
		
	}

}
